﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Entity;
using DAL;
using Common;
using System.Data.Linq;
namespace BAL
{
    public class Knowledge
    {
        private static string CacheName = "AllKnowledge";
        /// <summary>
        /// 写入缓存
        /// </summary>
        /// <returns></returns>
        public static void ToCache()
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                CacheHelper.Refurbish(CacheName, db.Knowledges.ToList(), 0, 60);
            }
        }
        public static int GetFirstId()
        {
            if (!CacheHelper.IsExist(CacheName))
            {
                ToCache();
            }
            IList<Models.Knowledge> cache = (IList<Models.Knowledge>)CacheHelper.GetCache(CacheName);
            return cache.First<Models.Knowledge>().Id;
        }


        /// <summary>
        /// 检查缓存状态，并读取缓存内容
        /// </summary>
        /// <returns>读取缓存中的内容</returns>
        public static IList<Models.Knowledge> CheckCache()
        {
            if (!CacheHelper.IsExist(CacheName)) { ToCache(); }
            return (IList<Models.Knowledge>)CacheHelper.GetCache(CacheName);
        }

        internal static KnowledgeInfo TransKnowledge2KnowledgeInfo(Models.Knowledge knowledge)
        {
            KnowledgeInfo knowledgeInfo = new KnowledgeInfo();

            Utility.SetObjectValueWithTheSamePropertyName(knowledgeInfo, knowledge);

            return knowledgeInfo;
        }
        public static KnowledgeInfo GetKnowledgeInfo(KnowledgeInfo knowledgeInfo)
        {
            

            if (knowledgeInfo.Parent != null)
            {
                knowledgeInfo.ParentKnowledgeInfo = GetKnowledgeInfoById(knowledgeInfo.Parent.Value);
            }
            return knowledgeInfo;
        }

        public static int GetKnowledgeIDByKeyword(string keyword,int subject)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Single(t => t.Keyword == keyword&&t.Subject==subject).Id;
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Single(t => t.Keyword == keyword).Id;
            //}
        }
        /*public static int GetKnowledgeIDOnlyBykeyword(string keyword) 
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Single(t => t.Keyword == keyword ).Id;
        }*/
        public static KnowledgeInfo GetKnowledgeInfoById(int Id)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            Models.Knowledge knowledge = Knowledge_Info.Single(b => b.Id == Id);
            return TransKnowledge2KnowledgeInfo(knowledge);
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    Models.Knowledge knowledge = db.Knowledges.Single(b => b.Id == Id);
            //    return TransKnowledge2KnowledgeInfo(knowledge);
            //}
        }
        public static IList<KnowledgeInfo> GetKnowledgeInfos(int knowledgeId)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            if (knowledgeId == 0)
                return Knowledge_Info.Where(c => c.Parent == 0).Select(c => TransKnowledge2KnowledgeInfo(c)).ToList();
            else
                return Knowledge_Info.Where(c => c.Parent == knowledgeId).Select(c => TransKnowledge2KnowledgeInfo(c)).ToList();
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    if (knowledgeId == 0)
            //        return db.Knowledges.Where(c => c.Parent == 0).Select(c => TransKnowledge2KnowledgeInfo(c)).ToList();
            //    else
            //        return db.Knowledges.Where(c => c.Parent == knowledgeId).Select(c => TransKnowledge2KnowledgeInfo(c)).ToList();
            //}
        }

        public static IList<KnowledgeInfo> GetRootKnowledgeInfo(int bookid,int subjectid)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(t => t.Subject == subjectid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(t => t.Subject == subjectid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //}
        }

        public static IList<KnowledgeInfo> GetRootKnowledgeInfo(int bookid)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(t => t.Book == bookid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(t => t.Book == bookid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //}
        }

        public static IList<KnowledgeInfo> GetKnowledgeInfos(int bookid, int subjectid)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            if (bookid > 0)
            {
                return Knowledge_Info.Where(t => t.Book == bookid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            }
            else
            {
                return Knowledge_Info.Where(t => t.Subject == subjectid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            }
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    if (bookid > 0)
            //    {
            //        return db.Knowledges.Where(t => t.Book == bookid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //    }
            //    else
            //    {
            //        return db.Knowledges.Where(t => t.Subject == subjectid && t.Parent == 0).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //    }
            //}
        }
        public static IList<KnowledgeInfo> GetKnowledgeInfosByBookId(int bookid)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(t => t.Book==bookid).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
        }

        public static IList<KnowledgeInfo> GetKnowledgeInfosBySubjectId(int subjectid)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            {
                return Knowledge_Info.Where(t => t.Subject.HasValue && t.Subject.Value == subjectid).OrderBy(p => p.Name).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            }
        }

        public static IList<KnowledgeInfo> GetKnowledgeInfos()
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //}
        }

        public static IList<KnowledgeInfo> GetKnowledgeInfosBySearch(string Keyowrd)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(t => t.Name.Contains(Keyowrd)).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(t => t.Name.Contains(Keyowrd)).Select(t => TransKnowledge2KnowledgeInfo(t)).ToList();
            //}
        }

        public static bool CheckKnowledgeExistSub(int KnowledgeID)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(t => t.Parent == KnowledgeID).Count() > 0;
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(t => t.Parent == KnowledgeID).Count() > 0;
            //}
        }

        public static bool CheckKnowledgeExistByKeyword(string keyword,int editid,int SubjectId)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            if (SubjectId == 0)
            {
                return Knowledge_Info.Where(t => t.Keyword == keyword && t.Id != editid).Count() > 0;
            }
            else
            {
                return Knowledge_Info.Where(t => t.Keyword == keyword && t.Id != editid && t.Subject == SubjectId).Count() > 0;
            }
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(t => t.Keyword == keyword && t.Id!=editid).Count() > 0;
            //}
        }

        public static bool CheckKnowledgeExist(KnowledgeInfo knowledgeInfo)
        {
            IList<Models.Knowledge> Knowledge_Info = CheckCache();
            return Knowledge_Info.Where(c => c.Keyword == knowledgeInfo.Keyword && c.Subject==knowledgeInfo.Subject || (c.Name == knowledgeInfo.Name && c.Parent == knowledgeInfo.Parent && c.Book == knowledgeInfo.Book && c.Subject == knowledgeInfo.Subject)).Count() > 0;
            //using (var db = DatabaseHelper.GetDashboardData())
            //{
            //    return db.Knowledges.Where(c => c.Keyword==knowledgeInfo.Keyword || (c.Name == knowledgeInfo.Name && c.Parent== knowledgeInfo.Parent && c.Book == knowledgeInfo.Book && c.Subject == knowledgeInfo.Subject)).Count() > 0;
            //}
        }

        public static KnowledgeInfo AddKnowledge(KnowledgeInfo knowledgeInfo)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                Models.Knowledge knowledge = new Models.Knowledge();

                Utility.SetObjectValueWithTheSamePropertyName(knowledge, knowledgeInfo);

                DatabaseHelper.Insert<Models.Knowledge>(knowledge);
                ToCache();
                return TransKnowledge2KnowledgeInfo(knowledge);
            }
        }
        public static void EditKnowledge(KnowledgeInfo knowledgeInfo)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                try
                {
                    Models.Knowledge knowledge = db.Knowledges.Single(b => b.Id == knowledgeInfo.Id && b.Subject==knowledgeInfo.Subject);

                    Utility.SetObjectValueWithTheSamePropertyName(knowledge, knowledgeInfo);
                    db.SubmitChanges(ConflictMode.ContinueOnConflict);
                    ToCache();
                }
                catch (ChangeConflictException)
                {
                    foreach (ObjectChangeConflict occ in db.ChangeConflicts)
                    {
                        occ.Resolve(RefreshMode.KeepCurrentValues);
                    }
                }

            }
        }

        public static void CasCadeDelKnowledge(int Id)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                List<Models.Knowledge> lstck = db.Knowledges.Where(b => b.Parent== Id).ToList();
                if (lstck != null)
                {
                    for (int i = 0; i < lstck.Count; i++)
                        CasCadeDelKnowledge(((Models.Knowledge)lstck[i]).Id);
                }
                List<Models.Knowledge> lst = db.Knowledges.Where(b => b.Id== Id).ToList();
                if (lst != null)
                {
                    DelKnowledge(GetArray<int>.Get(lst.Select(c => c.Id).ToList()));
                }
            }
        }

        public static void DelKnowledge(int id)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                DelKnowledge(new int[] { id });
            }
        }

        public static void DelKnowledge(int[] lstId)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                if (lstId.Length > 0)
                {
                    foreach (int id in lstId)
                    {
                        Question.DelQuestionByKnowledge(id);
                    }
                    string sql = string.Format("delete from Knowledge where id in ({0})", string.Join(",", lstId.ConvertToStringArray()));
                    db.ExecuteCommand(sql);
                    ToCache();
                }
            }
        }

        public static void DelKnowledgeBySubject(int SubjectId)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                int[] ids = db.Knowledges.Where(t => t.Subject == SubjectId).Select(t => t.Id).ToArray();
                DelKnowledge(ids);
                ToCache();
            }
        }

        public static void DelKnowledgeByBook(int BookID)
        {
            using (var db = DatabaseHelper.GetDashboardData())
            {
                int[] ids = db.Knowledges.Where(t => t.Book == BookID).Select(t=>t.Id).ToArray();
                DelKnowledge(ids);
                ToCache();
            }
        }
    }
}
